#pragma once
#include <string>
#include <iostream>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <strings.h>


//Sockaddr类，封装ip地址、port端口号、sockaddr_in结构，可以让我们更好地传参数
class Sockaddr
{
public:
    Sockaddr()
    {}
    // server初始化
    Sockaddr(in_port_t port)
        : _port(port), _len(sizeof(_addr_in))
    {
        bzero((void *)&_addr_in, sizeof(_addr_in));
        _addr_in.sin_family = AF_INET;
        _addr_in.sin_addr.s_addr = INADDR_ANY;
        _addr_in.sin_port = htons(_port);
    }

    // 用于服务器接收到信息后，拿到client端的信息传
    Sockaddr(const sockaddr_in &sock_in)
        : _addr_in(sock_in)
    {
        inet_ntop(AF_INET, &_addr_in.sin_addr, (char*)_ip.c_str(), sizeof(sock_in));
        _port = ntohs(_addr_in.sin_port);
        _len = sizeof(_addr_in);
    }

    Sockaddr(const Sockaddr& sr)
        : _ip(sr._ip)
        , _port(sr._port)
        , _addr_in(sr._addr_in)
        , _len(sr._len)
    {}

    //client初始化
    Sockaddr(std::string &ip, in_port_t port)
        : _ip(ip), _port(port), _len(sizeof(_addr_in))
    {
        bzero((void *)&_addr_in, sizeof(_addr_in));
        _addr_in.sin_family = AF_INET;
        inet_pton(AF_INET, ip.c_str(), &_addr_in.sin_addr);
        _addr_in.sin_port = htons(_port);
    }

    const Sockaddr &operator=(const Sockaddr &sr)
    {
        if (this != &sr)
        {
            _ip = sr._ip;
            _port = sr._port;
            _len = sr._len;

            _addr_in = sr._addr_in;
        }
        return *this;
    }

    ~Sockaddr()
    {}

    sockaddr_in &addr_in() { return _addr_in; }
    socklen_t &len() { return _len; }
    std::string &ip() { return _ip; }
    in_port_t port() { return _port; }

    std::string PrintDebug()
    {
        char buffer[100];
        snprintf(buffer, sizeof(buffer), "[%s][%d]", _ip.c_str(), _port);
        return buffer;
    }

    bool operator==(const Sockaddr &another)
    {
        return _ip == another._ip && _port == another._port;
    }

private:
    std::string _ip;
    in_port_t _port;
    sockaddr_in _addr_in; // 存放ip地址和port端口号的数据结构
    socklen_t _len;       // sockaddr_in的长度
};
